/*  newfs.h  */


/***************************************************************************/

typedef enum { FALSE, TRUE } BOOL;


/***************************************************************************/

  /* useful macros */

#define round_up_to_word(x) (((x)+3)&~3)


/***************************************************************************/

#define  DEBUG  1
#define  LOGFILE  "ADFS::Mike1.$.filesys.NewFS.logfile"   /* !!! */

#define  TRACE_UPCALLS 0  /* if 1, UpCalls are written out to the logfile */
                          /*   (must also set TRACE_UPCALLS in glue.s)    */

#define  TRACE_IO  0      /* if 1, read_bytes and write_bytes calls are   */
                          /*  written out to logfile                      */

/***************************************************************************/

#define IMAGE_TYPE      (0x333)             /* and why not ... */
#define IMAGE_TYPE_TEXT "333"

#define INFO_BLOCK_SIZE  (9)   /* size of an image filing system information
                                   block */


/***************************************************************************/

#define NEWFS_SWI_BASE  (0x0c2300)          /* and why not ... */

#define SWI_NEWFS_LAYOUTSTRUCTURE  (0)
#define SWI_NEWFS_DISCFORMAT       (1)

/***************************************************************************/

  /* defined in comms.c */

#define COMM_CHECKIMAGE  (0)
#define COMM_CRIMAGE     (1)
#define COMM_LISTIMAGE   (2)
#define COMM_LISTCBS     (3)
#define COMM_NEWFSLOG    (4)

extern void check_image(char *file_name);
extern void list_image(char *file_name);
extern void list_control_blocks(void);
extern void create_image
(
  char *file_name,
  char *image_name,
  int size,
  int block_size
);
extern void specify_logfile_name(char *file_name);


/***************************************************************************/

#define  MAX_STRING_LEN  (255)


/***************************************************************************/

  /* Definitions of NewFS image structures:

       An image file consists of an "image header" optionally followed by a
        number of "object"s.

       Each object consists of an "object header", followed by the "object
        name", followed by the "object contents"; each section is aligned
        to start on a word boundary.

       The image header and objects are always contiguous within the image
        file; any space remaining at the end is called "free space".
  */

#define  NEWFS_VERSION  (002)    /* identifies version of NewFS structures */

typedef enum
{
  TYPE_NOTFOUND = 0,
  TYPE_FILE = 1,
  TYPE_DIR = 2
} object_type;

  /* access permission bits */
#define  ATTR_READ    (0x01)
#define  ATTR_WRITE   (0x02)
#define  ATTR_LOCKED  (0x08)                          

  /* default attributes for files and directories */
#define  FILE_ATTR_DEFAULT (ATTR_READ+ATTR_WRITE)
#define   DIR_ATTR_DEFAULT (ATTR_READ+ATTR_WRITE)


#define  OPEN_ATTRS  0xc0000000  /* the image file information word returned
                                    by ImageEntry_Open */

#define  MAX_DISC_NAME  31

#define  NEWFS_ID  'NEWF'

typedef struct image_hdr
{
  int size;         /* size of image header in bytes - word-aligned */
  int version;      /* major*100 + minor */
  int block_size;   /* in bytes - must be a power of 2 between 64 and 1024 */
  int image_size;   /* offset of first word of free space */
  int boot_option;  /* boot option value */
  int stamp_value;  /* image stamp (ie disc id) */
  int id;           /* 'NEWF' */
  char image_name[MAX_DISC_NAME+1];
                    /* ie disc name */
} image_hdr;

typedef struct object_hdr
{
  int size;         /* size of object header in bytes - word-aligned */
  int load;         /* load address / filetype & part timestamp info */
  int exec;         /* exec address / more timestamp info */
  int attributes;   /* including access permissions */
  int extent;       /* file size in bytes (0 if a directory) */
  object_type type; /* may be a file or directory */
} object_hdr;

typedef struct object_name
{
  int size;          /* size of object name in bytes - word-aligned */
  char name[MAX_STRING_LEN+1]; 
                     /* name follows as null-terminated string */
} object_name;

typedef struct object_body
{
  int size;         /* size of body must be a multiple of the block_size */
  char contents[1]; /*  plus 4; the contents follow */
} object_body;


/***************************************************************************/

  /* Definitions of internal structures */

  /* An "image control block" - icb - is maintained for each image file
      registered with NewFS.

     Each such image is identified by the address of its icb.
  */

typedef struct icb
{
  struct icb *next;     /* pointer to next icb in list */
  int fswh;             /* FileSwitch's handle for the image file */
  int file_size;        /* size of the image file */
  BOOL stamp_pending;   /* TRUE iff outstanding "stamp image" request */
  image_hdr hdr;        /* copy of the image header */
} icb;

extern icb *image_list; /* addresses the list of registered images */

typedef icb *image_handle;

  /* Each open file is represented by a "file control block" or fcb.

     The file's handle is the address of this block.
  */

#define  OPEN_FOR_READ    (0)
#define  OPEN_FOR_UPDATE  (2)

typedef struct fcb
{
  struct fcb *next;     /* pointer to next fcb in list */
  image_handle ih;      /* points to icb of corresponding image */
  int hdr_pos;          /* offset of object header in the image file */
  int pos;              /* offset of object body content in the image file */
  int reason;           /* OPEN_FOR_READ or OPEN_FOR_UPDATE */
} fcb;

extern fcb *file_list;  /* addresses the list of open files */

typedef fcb *file_handle;


/***************************************************************************/

typedef struct FS_open_block
{
  int file_info_word;
  file_handle handle;
  int buff_size;
  int extent;
  int allocated;
} FS_open_block;

typedef struct FS_datestamp
{
  int load;
  int exec;
} FS_datestamp;

typedef struct FS_dir_entry
{
  int obj_type;
  int load;
  int exec;
  int length;
  int attributes;
} FS_dir_entry;

typedef struct FS_dir_block
{
  int num_read;
  int next_offset;
} FS_dir_block;

typedef struct FS_entry_info
{
  int load;
  int exec;
  int length;
  int attributes;
  int obj_type;
  char name[4];   /* NULL terminated filename */
} FS_entry_info;

typedef struct FS_free_space
{
  int free_space;
  int largest_object;
  int disc_size;
} FS_free_space;


/***************************************************************************/

  /* static parameter blocks to return values to FileSwitch */

extern FS_open_block open_file_PB;
extern FS_datestamp time_stamp_PB;
extern FS_dir_entry dir_entry_PB;
extern FS_dir_block dir_read_PB;
extern FS_free_space space_info_PB;


/***************************************************************************/

  /* defined in newfs.c */

extern _kernel_oserror *fs_commands(char *argv, int argc,
                                    int command, void *private);
extern _kernel_oserror *fs_swi(int swi_no,
                               _kernel_swi_regs *rset, void *private);
extern int init_fs(char *cmd_tail, int podule_base, void *private);
extern void fs_service(int service_number,
                       _kernel_swi_regs *rset, void *private);


/***************************************************************************/

  /* defined in glue.s */

  /* assembler functions provided to support the C module world */

extern char *module_name(void);               /* ASCII module name */
extern int *module_base;                      /* module address in RMA */

 /* load/store non-aligned 32-bit values */
extern void write_word(char *address, int datavalue);
extern int load_word(char *address);

 /* validate address range */
extern BOOL validate_buffer(int addr1, int addr2);

 /* FileSwitch interface functions - ImageEntry_... */
extern void NewFS_Open(void);
extern void NewFS_GetBytes(void);
extern void NewFS_PutBytes(void);
extern void NewFS_Args(void);
extern void NewFS_Close(void);
extern void NewFS_File(void);
extern void NewFS_Func(void);

/***************************************************************************/

  /* defined in general.c */

  /* this buffer is used when moving objects within the image file to keep
      it compact */
#define  COPY_BUFF_SIZE  512
extern char copy_buffer[];

extern void read_bytes(image_handle ih, char *buff, int n, int pos);
extern void write_bytes(image_handle ih, char *buff, int n, int pos);

extern void *check_alloc(int n);
extern void check_free(void *p);

extern BOOL for_each_object
(
  image_handle ih,
  BOOL f(image_handle ih, int pos, void *handle),
  void *handle
);

  /* these two variables point to malloc'd storage areas are used to contain
      information about the "current object" during a "for_each_object(..)"
      enumeration */

extern object_hdr curr_obj_hdr;
extern object_name curr_obj_name;

extern int curr_obj_pos;           /* address of curr_obj_hdr in the image */

extern void read_obj_hdr_and_name(image_handle ih, int pos);
extern void read_obj_name(image_handle ih, int pos);
extern void read_obj_hdr(image_handle ih, int pos);

extern BOOL is_in_dir(char *dir_name, char *obj_name);
extern BOOL equal_names(char *name1, char *name2);
extern BOOL equal_prefixes(char *name1, char *name2, int n);

extern void delete_object(image_handle ih, int pos);

extern int round_up_to_block(image_handle ih, int x);

extern void copy_up(image_handle ih, int from, int gap, int size);
extern void copy_down(image_handle ih, int from, int gap, int size);


/***************************************************************************/

  /* defined in ops.c */

extern FS_open_block *NewFS_open_file
(
  int reason,
  char *fname,
  image_handle ihand
);

extern int NewFS_get_bytes
(
  file_handle fhand,
  char *memaddr,
  int bytes,
  int foff
);

extern int NewFS_put_bytes
(
  file_handle fhand,
  char *ma,
  int bytes,
  int foff,
  char dbyte
);

extern int NewFS_close_file
(
  file_handle fhand,
  int loadaddr,
  int execaddr
);

extern int NewFS_write_extent
(
  file_handle fhand,
  int fext
);

extern int NewFS_alloc
(
  file_handle fhand
);

extern FS_datestamp *NewFS_flush
(
  file_handle fhand
); 

extern int NewFS_ensure
(
  file_handle fhand,
  int ensure
);

extern int NewFS_write_zeros
(
  file_handle fhand,
  int foff,
  int bytes
);

extern FS_datestamp *NewFS_read_datestamp
(
  file_handle fhand
);

extern char *NewFS_save_file
(
  char *fname,
  int ld,
  int ex,
  char *base,
  char *end,
  image_handle ihand
);

extern FS_dir_entry *NewFS_read_cat
(
  char *fname,
  image_handle ihand
);

extern int NewFS_write_cat
(
  char *fname,
  int ld,
  int ex,
  int attr,
  image_handle ihand
);

extern FS_dir_entry *NewFS_delete
(
  char *fname,
  image_handle ihand
);

extern int NewFS_create
(
  char *fname,
  int ld,
  int ex,
  char *base,
  char *end,
  image_handle ihand
);

extern int NewFS_create_dir
(
  char *fname,
  int ld,
  int ex,
  int size,
  image_handle ihand
);

extern int NewFS_read_block_size
(
  char *filename,
  image_handle ihand
);

extern int NewFS_rename
(
  char *oldname,
  char *newname,
  image_handle ihand
);

extern FS_dir_block *NewFS_read_dir
(
  char *name,
  char *buff,
  int num,
  int first,
  int length,
  image_handle ih
);

extern FS_dir_block  *NewFS_read_dir_info
(
  char *name,
  char *buff,
  int num,
  int first,
  int length,
  image_handle ih
);

extern image_handle NewFS_image_open
(
  int fshand,
  int buffsize
);

extern int NewFS_image_close
(
  image_handle ihand
);

extern int NewFS_defect_list
(
  int buffer,
  int blen,
  image_handle ihand
);

extern int NewFS_add_defect
(
  int offset,
  image_handle ihand
);

extern int NewFS_read_boot_option
(
  image_handle ihand
);

extern int NewFS_write_boot_option
(
  int newoption,
  image_handle ihand
);

extern int NewFS_used_space_map
(
  char *buffer,
  int blen,
  image_handle ihand
);

extern FS_free_space *NewFS_read_free_space
(
  image_handle ihand
);

extern int NewFS_namedisc
(
  char *newname,
  image_handle ihand
);

extern int NewFS_stampimage
(
  int type,
  image_handle ihand
);

extern int NewFS_objectatoffset
(
  int offset,
  char *buffer,
  int blen,
  image_handle ihand
);


/***************************************************************************/

  /* defined in layout.c */

extern _kernel_oserror *layout_image
(
  int fswh,
  char *image_name,
  int block_size
);
extern _kernel_oserror *NewFS_LayoutStructure
(
  _kernel_swi_regs *rset,
   void *private
);

/***************************************************************************/

  /* defined in errors.c */

extern char logfile[];

extern void debug(char *format, ...);

extern _kernel_oserror err_blk;
extern _kernel_oserror *_syserr;

extern _kernel_oserror *global_error(int errnum);
extern _kernel_oserror *global_errorV(char *format, ...);

#define  NOT_SUPPORTED  (0xd8)
#define  NO_STACK       (0xa5)
#define  BAD_PAR_ARGS   (0x00)
#define  BAD_PAR_FILE   (0x01)
#define  BAD_PAR_FUNC   (0x02)


/***************************************************************************/

  /* defined in formident.c */

 /* structure for EnumerateFormats SWI */
typedef struct format_spec
{
  struct format_spec *next;
  char *submenu_text;
  char *help_text;
  int format_swi_number;
  int format_arg;
  int layout_swi_number;
  int layout_arg;
  int flags;
} format_spec;

 /* disc format structure passed to NewFS_DiscFormat(..) */
typedef struct format_str
{
  int sector_size;
  int gap1_side0;
  int gap1_side1;
  int gap3;
  char sectors_per_track;
  char density;
  char options;
  char start_sector_number;
  char interleave;
  char side_skew;
  char track_skew;
  char fill_value;
  int tracks;
  char reserved[36];
} format_str;

 /* disc record structure passed to NewFS_IdentifyDisc(..) - see p. 2-202 */
typedef struct disc_rec
{
  char log2secsize;
  char secspertrack;
  char heads;
  char density;
  char idlen;
  char log2bpmb;
  char skew;
  char bootoption;
  char lowsector;
  char nzones;
  char zone_spare[2];
  int root;
  int disc_size;
  char disc_id_lo;
  char disc_id_hi;
  char disc_name[10];
  int disc_type;
  char reserved[24];
} disc_rec;


extern _kernel_oserror *display_format_help(void);
extern BOOL identify_format(char *format_id,
                            int *format_arg, int *layout_arg);
extern _kernel_oserror *add_format_info(format_spec **list);
extern _kernel_oserror *NewFS_DiscFormat(_kernel_swi_regs *r, void *private);

extern BOOL identify_disc
(
  disc_rec *drec,
  char *curr_format_buff,
  int buff_size,
  int *cache_ptr,
  int private,
  int *image_type
);


/***************************************************************************/
